import paho.mqtt.client as mqtt
import logging
import time
import json

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# 终端状态字典
client_status = {}


# MQTT 回调函数（使用API版本2，添加properties参数）
def on_connect(client, userdata, flags, rc, properties=None):  # 新增properties参数
    if rc == 0:
        logger.info("成功连接到MQTT服务器")
        # 订阅所有客户端连接/断开事件  ;$SYS/brokers/emqx@172.18.0.4/clients/mqttx_7b693d31/connected
        # client.subscribe("$SYS/brokers/+/clients/#", qos=1)
        # 示例2：同时订阅多个主题（用字典指定不同QoS）
        client.subscribe([
            ("$SYS/brokers/+/clients/#", 1),  # 原$SYS系统主题,用来检测其他终端上下线
            ("cx/jia/#", 1)  # 业务主题（带通配符），QoS=1
        ])
    else:
        logger.error(f"连接失败，错误码: {rc}")


def on_message(client, userdata, msg, properties=None):  # 新增properties参数
    try:
        topic = msg.topic
        payload = msg.payload.decode('utf-8')
        logger.info(f"收到主题: {topic}，消息: {payload}")
        """
        {"ipaddress":"192.168.1.12",
        "expiry_interval":0,"clean_start":true,
        "sockport":1883,"connected_at":1754383913919,
        "proto_ver":4,"proto_name":"MQTT",
        "clientid":"mqttx_7b693d31","username":"cs02",
        "ts":1754383913919,"protocol":"mqtt","keepalive":60}
        """
        # 解析payload为JSON字典（核心步骤）
        try:
            payload_data = json.loads(payload)  # 解析为字典
        except json.JSONDecodeError:
            # 若解析失败，存储原始字符串并记录警告
            payload_data = {"raw_data": payload}
            logger.warning(f"payload格式不是JSON: {payload}")

        # 首先分流
        topics = payload_data.get("topic", "topic")
        if topics != "topic":
            qingQiuLeiXing = payload_data.get("qingQiuLeiXing", "qingQiuLeiXing")
            weiZhi = payload_data.get("weiZhi", "weiZhi")
            sheBei = payload_data.get("sheBei", "sheBei")
            zhuangTai = payload_data.get("zhuangTai", "zhuangTai")
            match topics:
                case "cx/jia":
                    pass
                case "cx/che":
                    pass
                case _:
                    pass

        else: # 终端上下线处理
            # 解析客户端ID
            parts = topic.split('/')
            # 主题至少需要6个部分（如$SYS/brokers/node/clients/clientid/connected）= $SYS/brokers/emqx@172.18.0.4/clients/mqttx_7b693d31/connected
            if len(parts) < 6:
                return

            client_id = parts[4]
            # 事件类型（connected/disconnected）位于索引5
            event_type = parts[5]

            # 处理上线事件
            if event_type == "connected":
                client_status[client_id] = {
                    "status": "online",
                    "timestamp": time.time(),
                    "info": payload_data  # 可解析JSON获取详细信息
                }
                username = payload_data.get("username", "未知")
                logger.info(f"终端上线: {client_id},用户名: {username}")
                # 发送消息到 cx/jia/temp 主题（匹配 cx/jia/# 通配符）
                client.publish(
                    topic="cx/jia/kt",  # 具体子主题，符合 cx/jia/# 规则
                    payload='{"temperature": 25.5, "unit": "℃"}',  # JSON格式字符串
                    qos=1  # 与订阅的QoS一致
                )

            # 处理下线事件
            elif event_type == "disconnected":
                client_status[client_id] = {
                    "status": "offline",
                    "timestamp": time.time(),
                    "info": payload_data
                }
                username = payload_data.get("username", "未知")
                logger.info(f"终端下线: {client_id},用户名: {username}")

            # 打印终端状态汇总
            # print_status_summary()

    except Exception as e:
        logger.error(f"处理消息时出错: {e}")


# 打印终端状态汇总
def print_status_summary():
    logger.info("\n===== 终端在线状态汇总 =====")
    for client_id, info in client_status.items():
        status = info["status"]
        timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(info["timestamp"]))
        logger.info(f"{client_id}: {status} (时间: {timestamp})")
    logger.info("===========================\n")


# 创建MQTT客户端时显式指定回调API版本为2（推荐）
client = mqtt.Client(
    client_id="fuWuQi",
    clean_session=True,
    protocol=mqtt.MQTTv311,
    callback_api_version=mqtt.CallbackAPIVersion.VERSION2  # 新增此行，指定API版本
)

# 设置回调函数
client.on_connect = on_connect
client.on_message = on_message

# 设置用户名和密码（根据你的EMQ X配置调整）
client.username_pw_set(username="f001", password="cx123100")

try:
    logger.info("正在连接到MQTT服务器...")
    client.connect("192.168.1.88", 1883, 60)
    client.loop_forever()
except KeyboardInterrupt:
    logger.info("程序被用户中断")
    client.disconnect()
except Exception as e:
    logger.error(f"发生异常: {e}")
    client.disconnect()
